package cn.fl.riskctrl.acard.service.impl;

import cmm.mid.core.framework.dto.BaseParamDTO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.fl.commons.result.ResponseData;
import cn.fl.project.service.IPrjBscInfoService;
import cn.fl.project.service.IPrjQuatPrpsFeeService;
import cn.fl.project.vo.PrjBscInfoVO;
import cn.fl.riskctrl.acard.service.IAcardService;
import com.alibaba.fastjson.JSONObject;
import fl.riskctrl.facade.resmgt.acard.api.IRcACardComplexApiService;
import fl.riskctrl.facade.resmgt.acard.constant.AcardOptTypEnum;
import fl.riskctrl.facade.riskctrl.acard.dto.RcACardToPcResultDTO;
import fl.riskctrl.facade.riskctrl.acard.dto.RcCpModExtInfoDTO;
import fl.riskctrl.facade.riskctrl.acard.dto.RcSpModExtInfoDTO;
import fl.riskctrl.facade.riskctrl.api.IRiskCtrlSearchApiService;
import fl.riskctrl.facade.riskctrl.dto.DataResultDTO;
import fl.riskctrl.facade.riskctrl.dto.RcCstBscInfoDTO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import rc.gateway.facade.gateway.api.base.IBaseRcGatewayServiceApiService;
import rc.gateway.facade.gateway.dto.RcGatewayServiceSergwrDTO;
import rc.riskctrl.facade.resmgt.acard.condition.PreAuditQc;
import rc.riskctrl.facade.resmgt.acard.dto.PreAuditResult;

import java.util.ArrayList;
import java.util.List;

@Service
public class AcardSearchServiceImpl implements IAcardService {

    private static final Logger logger = LoggerFactory.getLogger(AcardSearchServiceImpl.class);
    @Autowired
    private IPrjBscInfoService prjBscInfoService;
    @Autowired
    private IPrjQuatPrpsFeeService prjQuatPrpsFeeService;
    /**
     * A卡详版接口
     */
    @Autowired
    private IRcACardComplexApiService rcACardComplexApiService;
    @Autowired
    private IRiskCtrlSearchApiService riskCtrlSearchApiService;
    @Autowired
    private IBaseRcGatewayServiceApiService rcGatewayServiceApiService;

    /**
     * 重新计算A卡征信信息
     */
    @Override
    public DataResultDTO reCalculateAcard(Long prjId) throws BaseException {
        BaseLogUtils.info(logger, "reCalculateAcard", "计算A卡详版开始.参数prjId=" + prjId);
        String msg = "操作失败!";
        int success = BaseConstant.IS_YESNO_NO;
        BaseParamDTO baseParamDTO = new BaseParamDTO();
        DataResultDTO result = new DataResultDTO(BaseConstant.IS_YESNO_NO,msg);
        RcACardToPcResultDTO resultDTO = new RcACardToPcResultDTO();
        try {
            //数据校验
            PrjBscInfoVO prjBscInfo = prjBscInfoService.selectById(prjId);
            if (null == prjBscInfo) {
                msg = "A卡详版-获取基本项目信息失败!";
                BaseLogUtils.error(logger, "reCalculateAcard", msg);
                throw new BaseException(msg);
            }
            Long rcCstBscInfoId = prjBscInfo.getRcCstBscInfoId();
            RcCstBscInfoDTO dto = riskCtrlSearchApiService.getRcCstBscInfoById(rcCstBscInfoId);
            if (null == rcCstBscInfoId || null == dto) {
                msg = "A卡详版-前置客户信息失败!";
                BaseLogUtils.error(logger, "reCalculateAcard", msg);
                throw new BaseException(msg);
            }
            // 获取简版信息
            DataResultDTO spExtInfo = rcACardComplexApiService.getRcSpModExtInfo(dto.getRcSpModExtInfoId(),baseParamDTO);
            if (BaseConstant.IS_YESNO_NO == spExtInfo.getSuccess() || null == spExtInfo.getData()) {
                msg = "A卡详版-未查询到A卡简版信息!";
                BaseLogUtils.error(logger, "getNewAcardResult", msg);
                throw new BaseException(msg);
            }
            //获取详版信息
            List<RcCpModExtInfoDTO> list = getCpModExtInfoList(prjId, dto, baseParamDTO);
            // 解析显示信息
            resultDTO = getShowResultV2((RcSpModExtInfoDTO) spExtInfo.getData(), list, dto);
            success = BaseConstant.IS_YESNO_YES;
            msg = "A卡详版计算成功！";
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            msg = "计算A卡详版失败!";
            BaseLogUtils.error(logger, "reCalculateAcard", msg, e);
            throw new BaseException(msg);
        } finally {
            result.setData(resultDTO);
            result.setInfo(msg);
            result.setSuccess(success);
        }
        BaseLogUtils.info(logger, "reCalculateAcard", "计算A卡详版结果result=" + JSONObject.toJSONString(result));
        return result;
    }

    /**
     * 计算预审审核A卡征信信息
     * @methodName reCalculateAcard
     * @author: tanbin@shiqiao.com
     * @createDate: 2021/1/27 14:21
     * @version: V1.0.0
     * @param prjId
     * @Return fl.riskctrl.facade.riskctrl.dto.DataResultDTO
     * @updateRemark [序号][YYYY-MM-DD] [更改人姓名][变更描述]
     */
    @Override
    public DataResultDTO reCalculateYsAcard(Long prjId,Long rcCstBscInfoId) throws BaseException {
        BaseLogUtils.info(logger, "reCalculateYsAcard", "计算A卡预审审核开始.参数prjId=" + prjId);
        String msg = "操作失败!";
        int success = BaseConstant.IS_YESNO_NO;
        BaseParamDTO baseParamDTO = new BaseParamDTO();
        DataResultDTO result = new DataResultDTO(BaseConstant.IS_YESNO_NO,msg);
        RcACardToPcResultDTO resultDTO = new RcACardToPcResultDTO();
        try {
            //数据校验
            PrjBscInfoVO prjBscInfo = prjBscInfoService.selectById(prjId);
            if (null == prjBscInfo) {
                msg = "A卡预审审核-获取基本项目信息失败!";
                BaseLogUtils.error(logger, "reCalculateAcard", msg);
                throw new BaseException(msg);
            }
            if (null == rcCstBscInfoId) {
                msg = "A卡预审审核-前置客户ID为空!";
                BaseLogUtils.error(logger, "reCalculateAcard", msg);
                throw new BaseException(msg);
            }
            RcCstBscInfoDTO dto = riskCtrlSearchApiService.getRcCstBscInfoById(rcCstBscInfoId);
            if (null == rcCstBscInfoId || null == dto) {
                msg = "A卡预审审核-前置客户信息失败!";
                BaseLogUtils.error(logger, "reCalculateAcard", msg);
                throw new BaseException(msg);
            }
            // 获取预审审核信息
            RcGatewayServiceSergwrDTO rcGatewayServiceSergwrDTO = new RcGatewayServiceSergwrDTO();
            rcGatewayServiceSergwrDTO.setPid("ca0022d8e462494ab1610872f7c7e7e3");
            rcGatewayServiceSergwrDTO.setBid("867faa25f0c340dd93375afff6de166a");
            rcGatewayServiceSergwrDTO.setMethodCode("SGWM_10009");
            List<Object> params = new ArrayList<>();
            PreAuditQc preAuditQc = new PreAuditQc();
            preAuditQc.setPrjId(prjId);
            preAuditQc.setRcCstBscInfoId(rcCstBscInfoId);
            params.add(preAuditQc);
            params.add(baseParamDTO);
            rcGatewayServiceSergwrDTO.setParamters(params);
            ResponseData<PreAuditResult> responseData = rcGatewayServiceApiService.execute(rcGatewayServiceSergwrDTO);
            if (responseData.isSuccess() != true || !ResponseData.SUCCESS_CODE.equals(responseData.getCode())){
                msg = responseData.getMessage();
                BaseLogUtils.error(logger, "reCalculateAcard", msg);
                throw new BaseException(msg);
            }
            PreAuditResult preAuditResult = responseData.getData();
            // 解析显示信息
            resultDTO = getShowResultV3(preAuditResult, dto);
            success = BaseConstant.IS_YESNO_YES;
            msg = "A卡预审审核计算成功！";
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            msg = "计算A卡预审审核失败!";
            BaseLogUtils.error(logger, "reCalculateAcard", msg, e);
            throw new BaseException(msg);
        } finally {
            result.setData(resultDTO);
            result.setInfo(msg);
            result.setSuccess(success);
        }
        BaseLogUtils.info(logger, "reCalculateAcard", "计算A卡预审审核结果result=" + JSONObject.toJSONString(result));
        return result;
    }


    /**
     * 获取A卡详版模型
     *
     * @param
     * @methodName getCpModExtInfoList
     * @author: chenjunnan@lionbridgecapital.cn
     * @createDate: 2019/8/7 17:41
     * @version: V1.0.0
     * @Return java.util.List<fl.riskctrl.facade.riskctrl.acard.dto.RcCpModExtInfoDTO>
     * @updateRemark [序号][YYYY-MM-DD] [更改人姓名][变更描述]
     */
    private List<RcCpModExtInfoDTO> getCpModExtInfoList(Long prjId, RcCstBscInfoDTO dto, BaseParamDTO baseParamDTO) throws BaseException {
        BaseLogUtils.info(logger, "getCpModExtInfoList", "获取A卡详版模型信息开始.prjId=" + prjId + "dto=" + JSONObject.toJSONString(dto));
        String msg = "";
        List<RcCpModExtInfoDTO> list = null;
        try {
            // 详版数据
            DataResultDTO cpExtInfo = rcACardComplexApiService.getRcCpModExtInfo(prjId, dto.getId(), baseParamDTO);
            list = (List<RcCpModExtInfoDTO>) cpExtInfo.getData();
            if (CollectionUtils.isNotEmpty(list)) {
                return list;
            }
            DataResultDTO  resultDTO= rcACardComplexApiService.getACardComplexPub(prjId, AcardOptTypEnum.FLOW, baseParamDTO);
            if(BaseConstant.IS_YESNO_NO == resultDTO.getSuccess()){
                msg = resultDTO.getInfo();
                BaseLogUtils.error(logger, "getCpModExtInfoList", msg);
                throw new BaseException(msg);
            }
            // 再次获取信息
            cpExtInfo = rcACardComplexApiService.getRcCpModExtInfo(prjId, dto.getId(), baseParamDTO);
            list = (List<RcCpModExtInfoDTO>) cpExtInfo.getData();
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            msg = "获取A卡详版模型失败!";
            BaseLogUtils.error(logger, "getCpModExtInfoList", msg, e);
            throw new BaseException(msg);
        }
        return list;
    }

    /**
     * A卡详版结果拼装
     *
     * @param rcSpModExtInfoDTO
     * @param list
     * @param dto
     * @methodName getShowResultV2
     * @author: chenjunnan@lionbridgecapital.cn
     * @createDate: 2019/8/5 17:36
     * @version: V1.0.0
     * @Return fl.riskctrl.facade.riskctrl.acard.dto.RcACardToPcResultDTO
     * @updateRemark [序号][YYYY-MM-DD] [更改人姓名][变更描述]
     */
    private RcACardToPcResultDTO getShowResultV2(RcSpModExtInfoDTO rcSpModExtInfoDTO, List<RcCpModExtInfoDTO> list, RcCstBscInfoDTO dto) throws BaseException {
        BaseLogUtils.info(logger, "getShowResultV2", "A卡详版-出结果开始.入参rcSpModExtInfoDTO=" + JSONObject.toJSONString(rcSpModExtInfoDTO) + "list=" + JSONObject.toJSONString(list)
                + "dto=" + JSONObject.toJSONString(dto));
        RcACardToPcResultDTO result = new RcACardToPcResultDTO();
        String msg = "";
        try {
            // 购车类型
            result.setPrdTypCd(dto.getPrdTypCd());
            //二手车、车抵贷不显示简版和详版信息
            if ("5".equals(dto.getPrdTypCd()) || "cddunderline".equals(dto.getPrdTypCd())){
                result.setaCardSPLabelNm("   ");
                return result;
            }
            // 简版
            result.setaCardSPLabelNm("A卡简版提示:");
            result.setaCardSPResult(dto.getAudStsDesc());
            result.setaCardSpResult_2(rcSpModExtInfoDTO.getSchr9());
            if (CollectionUtils.isEmpty(list)) {
                return result;
            }
            // 详版
            for (RcCpModExtInfoDTO obj : list) {
                String datTyp = obj.getDatTyp();
                if ("before".equals(datTyp)) {
                    // before 的显示
                    result.setaCardCPBeforeLabelNm("A卡详版提示：");
                    result.setaCardCPBeforeResult("1、审核提示信息：" + getTipTiles(obj.getSchr6()) + "2、首付比例+保证金比例：" + obj.getSchr13());
                } else {
                    // after 的显示
                    result.setaCardCPAfterLabelNm("A卡详版提示：");
                    result.setaCardCPAfterResult("1、审核提示信息：" + getTipTiles(obj.getSchr6()) + "2、首付比例+保证金比例：" + obj.getSchr13());
                }
            }
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            msg = "计算A卡详版-出结果描述异常!";
            BaseLogUtils.error(logger, "getShowResultV2", msg, e);
            throw new BaseException(msg);
        }
        BaseLogUtils.info(logger, "getShowResultV2", "A卡详版-出结果结束，result=" + JSONObject.toJSONString(result));
        return result;
    }

    private RcACardToPcResultDTO getShowResultV3(PreAuditResult preAuditResult,RcCstBscInfoDTO dto) throws BaseException {
        BaseLogUtils.info(logger, "getShowResultV3", "A卡预审审核-出结果开始.preAuditResult=" + JSONObject.toJSONString(preAuditResult));
        RcACardToPcResultDTO result = new RcACardToPcResultDTO();
        String msg = "";
        try {
            // 购车类型
            result.setPrdTypCd(dto.getPrdTypCd());
            // 简版
            result.setaCardSPLabelNm("A卡简版提示:");
            result.setaCardSPResult(preAuditResult.getAudStsDesc());
            result.setaCardSpResult_2(preAuditResult.getCarsDesc());
            result.setaCardCPAfterLabelNm("A卡详版提示：");
            result.setaCardCPAfterResult("审核提示信息："+ preAuditResult.getPreDetailedAudDesc());
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            msg = "A卡预审审核-出结果描述异常!";
            BaseLogUtils.error(logger, "getShowResultV3", msg, e);
            throw new BaseException(msg);
        }
        BaseLogUtils.info(logger, "getShowResultV2", "A卡预审审核-出结果结束，result=" + JSONObject.toJSONString(result));
        return result;
    }

    private String getTipTiles(String tips) {
        if (StringUtils.isEmpty(tips)) {
            return "正常审批";
        }
        switch (tips) {
            case "0":
                return "正常审批";
            case "1":
                return "快速审批";
            case "2":
                return "仅告知";
            case "3":
                return "征信白户，正常审批";
            default:
                return "正常审批";
        }
    }
}
